home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / tex / cawf404.zip / cawf.c < prev    next >
C/C++ Source or Header  |  1993-12-07  |  16KB  |  648 lines

  1. /*
  2.  *    cawf - a C version of Henry Spencer's awf(1), the Amazingly
  3.  *           Workable (text) Formatter
  4.  *
  5.  *    V. Abell, Purdue University Computing Center
  6.  */
  7.  
  8. /*
  9.  *    Copyright (c) 1991 Purdue University Research Foundation,
  10.  *    West Lafayette, Indiana 47907.  All rights reserved.
  11.  *
  12.  *    Written by Victor A. Abell <abe@mace.cc.purdue.edu>,  Purdue
  13.  *    University Computing Center.  Not derived from licensed software;
  14.  *    derived from awf(1) by Henry Spencer of the University of Toronto.
  15.  *
  16.  *    Permission is granted to anyone to use this software for any
  17.  *    purpose on any computer system, and to alter it and redistribute
  18.  *    it freely, subject to the following restrictions:
  19.  *
  20.  *    1. The author is not responsible for any consequences of use of
  21.  *       this software, even if they arise from flaws in it.
  22.  *
  23.  *    2. The origin of this software must not be misrepresented, either
  24.  *       by explicit claim or by omission.  Credits must appear in the
  25.  *       documentation.
  26.  *
  27.  *    3. Altered versions must be plainly marked as such, and must not
  28.  *       be misrepresented as being the original software.  Credits must
  29.  *       appear in the documentation.
  30.  *
  31.  *    4. This notice may not be removed or altered.
  32.  */
  33.  
  34. static char Version[] = "4.04";
  35.  
  36. #include "cawf.h"
  37.  
  38. #include <time.h>
  39.  
  40. #include <sys/stat.h>
  41. #ifndef    UNIX
  42. #include <io.h>
  43. #include <process.h>
  44. #include <string.h>
  45. #include <sys\types.h>
  46. #include <sys\stat.h>
  47. #endif
  48.  
  49. static char *Month[] =
  50.     { "January", "February", "March", "April", "May", "June", "July",
  51.       "August", "September", "October", "November", "December" };
  52.  
  53.  
  54. main(argc, argv)
  55.     int     argc;
  56.     char    *argv[];
  57. {
  58.     char dt[32];            /* date for td and DY strings */
  59.     char *ep;                   /* environment pointer */
  60.     int fff = 0;            /* final form feed status */
  61.     char *files[MAXFILES];      /* file names */
  62.     int help = 0;            /* help status */
  63.     int i;                           /* temporary index */
  64.     size_t l;                       /* length */
  65.     char *lib = CAWFLIB;        /* library path */
  66.     int libl;            /* library path length */
  67.     struct tm *lt;            /* local time structure pointer */
  68.     int mac = 0;            /* macro specification status */
  69.     int nf = 0;                 /* number of files */
  70.     char *np;                   /* name pointer */
  71.     int pc;                     /* prolog count */
  72.     struct stat sbuf;               /* stat buffer */
  73.     time_t tm;            /* system time of day */
  74. /*
  75.  * Save program name.
  76.  */
  77.     if ((Pname = strrchr(argv[0], '\\')) != NULL)
  78.         Pname++;
  79.     else if ((Pname = strrchr(argv[0], '/')) != NULL)
  80.         Pname++;
  81.     else
  82.         Pname = argv[0];
  83. /*
  84.  * Set error file stream pointer.
  85.  */
  86.     Efs = stderr;
  87. /*
  88.  * Get library name.
  89.  */
  90.     if ((np = getenv("CAWFLIB")) != NULL)
  91.         lib = np;
  92.     libl = strlen(lib);
  93. /*
  94.  * Get device file name.
  95.  */
  96.     for (ep = getenv("TERM");; ep = NULL) {
  97.         if (ep == NULL || *ep == '\0')
  98.             ep = "dumb";
  99.         l = libl + 1 + strlen(ep) + strlen(".dev") + 1;
  100.         if ((np = malloc(l)) == NULL)
  101.             Error(FATAL, NOLINE,
  102.                 " no string space for device file: ", ep);
  103.         (void) sprintf(np, "%s/%s.dev", lib, ep);
  104.         if (stat(np, &sbuf) == 0)
  105.             break;
  106.         if (strcmp(ep, "dumb") == 0)
  107.             Error(FATAL, NOLINE, " no dumb.dev file in ", lib);
  108.         (void) free(np);
  109.     }
  110.     files[nf++] = np;
  111. /*
  112.  * Get common text file name.
  113.  */
  114.     l = libl + 1 + strlen("common") + 1;
  115.     if ((np = malloc(l)) == NULL)
  116.         Error(FATAL, NOLINE, " no string space for common file name",
  117.             NULL);
  118.     (void) sprintf(np, "%s/common", lib);
  119.     files[nf++] = np;
  120. /*
  121.  * Process options.
  122.  */
  123.     while ((i = getopt(argc, argv, "c:d:ef:hm:n:o:")) != EOF) {
  124.         switch (i) {
  125.     /*
  126.      * -c c
  127.      *
  128.      * Set the device configuration file path to c.
  129.      */
  130.         case 'c':
  131.             Devconf = optarg;
  132.             break;
  133.     /*
  134.      * -d d
  135.      *
  136.      * Set the output device name to d.
  137.      *
  138.      * The default output device name is NORMAL -- i.e., a device that
  139.      * does bold face with backspace and overprinting and italic face with
  140.      * underscore.  NORMAL is usually a terminal device.
  141.      *
  142.      * There is a built-in device, named ANSI, that does bold face with
  143.      * the ANSI shadow mode and italic face with the ANSI underscore mode.
  144.      * ANSI is normally a terminal device that supports the ANSI shadow
  145.      * and underscore modes.
  146.      *
  147.      * There is a built-in output device, named NONE, that does nothing
  148.      * at all for the bold or italic faces.  This is usually a terminal
  149.      * device.
  150.      *
  151.      * All other device names must match a stanza in the device
  152.      * configuration file.
  153.      */
  154.         case 'd':
  155.             Device = optarg;
  156.             break;
  157.     /*
  158.      * -e -- eject: issue final form feed
  159.      */
  160.         case 'e':
  161.             fff = 1;
  162.             break;
  163.     /*
  164.      * -f f
  165.      *
  166.      * Set f as the font name for the output device (from the device
  167.      * configuration file).
  168.      */
  169.         case 'f':
  170.             Devfont = optarg;
  171.             break;
  172.     /*
  173.      * -h -- display help (usage)
  174.      */
  175.         case 'h':
  176.             help = 1;
  177.             break;
  178.     /*
  179.      * -m m
  180.      *
  181.      * Set the macro file name to m.
  182.      *
  183.      *  Special support is provided for -man, -me and -ms.
  184.      */
  185.         case 'm':
  186.             if (mac) {
  187.                 Error(WARN, NOLINE,
  188.                     "multiple macro file declaration",
  189.                     NULL);
  190.                 break;
  191.             }
  192.             l = libl + 2 + strlen(optarg) + strlen(".mac") + 1;
  193.             if ((np = malloc(l)) == NULL)
  194.                 Error(FATAL, NOLINE, " no string space for ",
  195.                     argv[1]);
  196.             (void) sprintf(np, "%s/m%s.mac", lib, optarg);
  197.             files[nf++] = np;
  198.             if (strcmp(optarg, "an") == 0)
  199.                 Marg = MANMACROS;
  200.             else if (strcmp(optarg, "e") == 0)
  201.                 Marg = MEMACROS;
  202.             else if (strcmp(optarg, "s") == 0)
  203.                 Marg = MSMACROS;
  204.             mac++;
  205.             break;
  206.     /*
  207.      * -n n
  208.      *
  209.      * Set the starting page number to n.
  210.      */
  211.         case 'n':
  212.             Thispg = atoi(optarg);
  213.             break;
  214.     /*
  215.      * -o o
  216.      *
  217.      * Set the pages to print list from the string o.
  218.      *
  219.      * Entries are separated by commas.  A range is specified as n-m.
  220.      * A starting range of the form -m has one for a starting value,
  221.      * and a range of the form n- has an ending value equivalent to
  222.      * the end of the document.  For example:
  223.      *
  224.      *    -5,8,10-
  225.      *
  226.      * specifies the printing of pages 1 through 5, 8, and 10 through
  227.      * the end of the document.
  228.      */
  229.         case 'o':
  230.             if (!AsmPgRange(optarg))
  231.                 Error(WARN, NOLINE, "invalid page list: ",
  232.                     optarg);
  233.             break;
  234.     /*
  235.      * Option not recognized by getopt().
  236.      */
  237.         case '?':
  238.             Err = 1;
  239.         }
  240.     }
  241.     if (Defdev())
  242.         Err++;
  243.     if (help || Err) {
  244.       (void) fprintf(stderr,
  245.         "%s %s usage: [-c c] [-d d] [-e] [-f f] [-h] [-m m]\n",
  246.         Pname, Version);
  247.       (void) fprintf(stderr, "\t[-n n] [-o o] file...\n");
  248.       (void) fprintf(stderr,
  249.         "\t-c c      c is the device configuration file path\n");
  250.       (void) fprintf(stderr,
  251.         "\t          (default = %s/%s)\n", CAWFLIB, DEVCONFIG);
  252.       (void) fprintf(stderr,
  253.         "\t-d d      d is the output device name\n");
  254.       (void) fprintf(stderr,
  255.         "\t          (default = NORMAL, using \\b for bold and italic)\n");
  256.       (void) fprintf(stderr,
  257.         "\t          (built-ins = ANSI, NONE and NORMAL)\n");
  258.       (void) fprintf(stderr,
  259.         "\t-e        issue eject after last page\n");
  260.       (void) fprintf(stderr,
  261.         "\t-f f      f is the output device font name\n");
  262.       (void) fprintf(stderr,
  263.         "\t-h        display help (this output)\n");
  264.       (void) fprintf(stderr,
  265.         "\t-m m      m is the macro file name\n");
  266.       (void) fprintf(stderr,
  267.         "\t-n n      n is the starting page number\n");
  268.       (void) fprintf(stderr,
  269.         "\t-o o      o specifies output pages and page ranges\n");
  270.       (void) fprintf(stderr,
  271.         "\tfile ...  source file names\n");
  272.       exit(Err);
  273.     }
  274.     if (mac == 0) {
  275.  
  276.         /*
  277.          * No macros - enable Bold, Italic and Roman fonts.
  278.          */
  279.         for (i = 0; Fcode[i].nm; i++) {
  280.             switch (Fcode[i].nm) {
  281.             case 'B':
  282.             case 'I':
  283.             case 'R':
  284.                 Fcode[i].status = '1';
  285.             }
  286.         }
  287.     }
  288. /*
  289.  * Add user-supplied file names.
  290.  */
  291.     pc = nf;
  292.     if (optind >= argc) {
  293.         files[nf++] = NULL;       /* STDIN */
  294.     } else {
  295.         while (optind < argc) {
  296.             if (nf >= MAXFILES)
  297.                 Error(WARN, NOLINE, " too many files at ",
  298.                     argv[optind]);
  299.             files[nf++] = argv[optind++];
  300.         }
  301.     }
  302. /*
  303.  * Make sure all input files are accessible.
  304.  */
  305.     for (i = 0; i < nf; i++) {